<?php

namespace app\controller\admin;

use app\base\BaseEncryptController;
use app\factory\logistics\Logistics as Logistics;
use app\factory\Order as OrderFactory;
use app\model\order\OrderItemLogisticsModel;
use app\model\order\OrderItemModel;
use app\model\order\OrderModel;
use app\model\order\PayLogModel;
use app\model\system\LogisticsModel;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use think\Request;

/**
 * Order 订单
 * Class Order
 * @package app\controller
 */
class Order extends BaseEncryptController
{
    protected function initialize()
    {
        parent::initialize();
        $this->model = new OrderModel();

    }

    /**
     * 分页列表
     * @param string $status
     * @param string $keyword
     * @param int $page
     * @param int $limit
     * @param array $time_section
     * @param array $order_pt
     * @param string agency_id
     * @return \think\response\Json
     */
    public function getPage($status = '', $keyword = '', $page = 1, $limit = 10, $time_section = [], $order_pt = [], $agency_id = '')
    {
        $time = '';
        if (!empty($time_section)) {
            $time_start = strtotime($time_section[0]);
            $time_end = strtotime($time_section[1]);
            $time = [$time_start, $time_end];
        }
        if (empty($order_pt)) {
            $order_pt = "all";
        } else {
            $pt = in_array('拼团', $order_pt);
            $npt = in_array('不拼团', $order_pt);
            if ($pt && $npt) {
                $order_pt = "all";
            } else if ($pt) {
                $order_pt = "yes";
            } else {
                $order_pt = "no";
            }
        }
        $order = "a.create_time desc,a.order_status asc";
        $data = $this->model->getPageData($status, $keyword, $page, $limit, $time, $order_pt, $agency_id, $order);
        return self::returnMsg(1, [
            'totalCount' => $data['total'],
            'currentPage' => $data['current'],
            'pageList' => $data['dataList']
        ]);
    }

    /**
     * 获取支付日志列表
     * @param string $status
     * @param string $keyword
     * @param int $page
     * @param int $limit
     * @param array $time_section
     * @return \think\response\Json
     */
    public function getPayPage($status = '', $keyword = '', $page = 1, $limit = 10, $time_section = [])
    {
        $time = '';
        if (!empty($time_section)) {
            $time_start = strtotime($time_section[0]);
            $time_end = strtotime($time_section[1]);
            $time = [$time_start, $time_end];
        }
        $pay_log_model = new PayLogModel();
        $data = $pay_log_model->getPageData($status, $keyword, $page, $limit, "*", $time);
        return self::returnMsg(1, [
            'totalCount' => $data['total'],
            'currentPage' => $data['current'],
            'pageList' => $data['dataList']
        ]);
    }

    /**
     * 单条信息
     * @param $id
     * @return \think\response\Json
     */
    public function getInfo($id)
    {
        $field = "a.*,b.nick_name,c.agency_name";
        $data = $this->model->getChildInfo($id, $field);
        if (!empty($data)) {
            if (!empty($data['pay_date'])) {
                $data['pay_date'] = date("Y-m-d H:i:s", $data['pay_date']);
            } else {
                $data['pay_date'] = "";
            }
            return self::returnMsg(1, $data);
        } else {
            return self::returnMsg(1001);
        }
    }

    /**
     * 保存物流信息
     * @param Request $request
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onSaveLogistics(Request $request)
    {
        $item_id = $request->param("item_id");
        $item_number = $request->param("item_number");
        $order_id = $request->param("order_id");
        $formData = [
            "order_id" => $order_id,
            "logistics_code" => $request->param("code"),
            "logistics_number" => $request->param("number"),
            "remark" => $request->param("remark"),
        ];
        $formData['logistics_name'] = LogisticsModel::getLogisticsName($formData['logistics_code']);
        if (empty($order_id) || empty($item_id)) {
            $rsps['code'] = 991;
            $rsps['msg'] = "参数有误";
            return self::returnMsg($rsps);
        }
        if (strpos($item_id, ',') !== false) {
            $item_id = explode(',', $item_id);
        }
        if (strpos($item_number, ',') !== false) {
            $item_number_temp = explode(',', $item_number);
            $item_number = [];
            foreach ($item_number_temp as $key => $value) {
                $item_number[intval($item_id[$key])] = $value;
            }
        }
        $order_item_model = new OrderItemModel();
        $data_list = $order_item_model->getItemsInfo($order_id, $item_id, $item_number, true, 'system');//获取发货订单项
        $formData['order_item_info'] = $data_list;
        $order_model = new OrderModel();
        $map = [
            'id' => $order_id
        ];
        $order_data = $order_model->where($map)->field('order_status')->find();
        if ($order_data['order_status'] == 1) {
            $rsps['code'] = 0;
            $rsps['msg'] = "订单未付款";
            return self::returnMsg($rsps);
        } else if ($order_data['order_status'] == 4) {
            $rsps['code'] = 0;
            $rsps['msg'] = "订单已收货";
            return self::returnMsg($rsps);
        }
        $validate = 'app\validate\OrderValidate.CheckLogistics';
        $result = $this->validate($formData, $validate);
        if (true !== $result) {
            return self::returnMsg(991, [], $result);
        } else {
            $return_data = OrderItemLogisticsModel::addLogistics($formData, 'send', 0);
            return self::returnMsg($return_data['code'], [], $return_data['msg']);
        }
    }

    /**
     * 获取物流信息
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getLogisticsLog(Request $request)
    {
        $logistics_id = $request->param("logistics_id");
        $order_item_logistics_model = new OrderItemLogisticsModel();
        if (!empty($logistics_id)) {
            $logistics = $order_item_logistics_model->where('id', $logistics_id)->find();
            $Logistics_tool = new Logistics();
            $take_phone = "";
            if ($logistics['logistics_code'] == "SF") {
                $take_phone = OrderModel::getTakePhone($logistics['order_id']);
            }
            $logistics_log = json_decode($Logistics_tool->getOrderTracesByJson($logistics['order_id'], $logistics['logistics_code'], $logistics['logistics_number'], $take_phone), true);
            if (empty($logistics_log['Traces'])) {
                $rsps['data']['traces'] = [
                    'AcceptStation' => "暂无物流信息",
                    'AcceptTime' => date("Y-m-d H:i:s")
                ];
            } else {
                $rsps['data']['traces'] = array_reverse($logistics_log['Traces']);
            }
            $rsps['code'] = 1;
            return self::returnMsg($rsps);
        }
        $order_id = $request->param("id");
        $item_id = $request->param("item_id");
        $logistics_list = $order_item_logistics_model->where('order_id', $order_id)->select();
        $logistics = [];
        foreach ($logistics_list as &$value) {
            $value['item_list'] = json_decode($value['order_item_info'], true);
            if (empty($item_id)) {
                $logistics = $logistics_list[0];
            } else {
                if ($value['id'] == $item_id) {
                    $logistics = $value;
                }
            }
        }
        if ($logistics_list->isEmpty()) {
            $rsps['code'] = 0;
            $rsps['msg'] = "物流信息不存在";
            return self::returnMsg($rsps);
        }
        $Logistics_tool = new Logistics();
        $take_phone = "";
        if ($logistics['logistics_code'] == "SF") {
            $take_phone = OrderModel::getTakePhone($logistics['order_id']);
        }
        $logistics_log = json_decode($Logistics_tool->getOrderTracesByJson($logistics['order_id'], $logistics['logistics_code'], $logistics['logistics_number'], $take_phone), true);
        if (empty($logistics_log['Traces'])) {
            $rsps['data']['traces'] = [
                [
                    'AcceptStation' => "暂无物流信息",
                    'AcceptTime' => date("Y-m-d H:i:s")
                ]
            ];
        } else {
            $rsps['data']['traces'] = array_reverse($logistics_log['Traces']);
        }
        $rsps['code'] = 1;
        $rsps['data']['list'] = $logistics_list;
        return self::returnMsg($rsps);
    }

    /**
     * 获取未发货的商品信息
     * @param Request $request
     * @return \think\response\Json
     */
    public function getItemsInfo(Request $request)
    {
        $order_id = $request->param("id");
        $type = $request->param("type");
        $order_item_model = new OrderItemModel();
        $item_list = $order_item_model->getItemsInfo($order_id, [], [], true, $type);
        foreach ($item_list as &$value) {
            $value['now_send_number'] = $value['need_number'];
            $value['select'] = false;
        }
        $rsps['code'] = 1;
        $rsps['data'] = $item_list;
        $rsps['msg'] = "获取成功";
        return self::returnMsg($rsps);
    }

    /**
     * 获取物流公司列表
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onLogisticsAll()
    {
        $logistics_model = new LogisticsModel();
        $logistics_list = $logistics_model->getAll(['status' => 0]);
        return self::returnMsg(1, $logistics_list);
    }

    /**
     * 获取退款订单列表
     * @param string $status
     * @param string $out_handle_status
     * @param string $keyword
     * @param $page
     * @param $limit
     * @return \think\response\Json
     */
    public function onOutPage($status = "", $out_handle_status = "", $keyword = "", $page, $limit)
    {
        $data = $this->model->getOutPageData($status, $out_handle_status, $keyword, $page, $limit);
        return self::returnMsg(1, [
            'totalCount' => $data['total'],
            'currentPage' => $data['current'],
            'pageList' => $data['dataList']
        ]);
    }

    /**
     * 订单退款信息
     * @param Request $request
     * @return \think\response\Json
     */
    public function onOutInfo($id)
    {
        $data = $this->model->getOutInfo($id);
        if (!empty($data)) {
            return self::returnMsg(1, $data);
        } else {
            return self::returnMsg(1001);
        }
    }

    /**
     * 订单退款设置
     * @param Request $request
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onOrderOutEdit(Request $request)
    {
        $order_id = $request->param("id");
        $out_handle_status = $request->param("out_handle_status");
        if (empty($out_handle_status)) {
            return self::returnMsg(0, [], "请选择处理状态");
        }
        $out_not_text = $request->param("out_not_text");
        $OrderFactory = new OrderFactory();
        $res = $OrderFactory->outHandleStatus($order_id, $out_handle_status, $out_not_text);//微信退款
        return self::returnMsg($res);
    }

    /**
     * 删除
     * @param $id
     * @return \think\response\Json
     */
    public function onDelete($id)
    {
        $flag = $this->model::destroy(['id' => $id]);
        if (false !== $flag) {
            $this->model->delRedis($id);
            $this->model->redis->zRem($this->model->redis_key . ':rank', $id);
            $this->model->addToRecycle($id, 'OrderModel', '订单管理', $this->currentUser['user_id'], $this->currentUser['user_type'], 'order');
            return self::returnMsg(1);
        } else {
            return self::returnMsg(1002);
        }
    }

    /**
     * 确认收货
     * @param $id
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onConfirmTake($id)
    {
        $order_id = $id;
        $order_model = new OrderModel();
        $res = $order_model->confirmTake($order_id, 0, true);
        return self::returnMsg($res);
    }

    /**
     * 取消订单（已付款订单 退还支付金额）
     * @param $id
     * @return \think\response\Json
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onCancelOrder($id)
    {
        $res['code'] = 0;
        $res['msg'] = "取消失败";
        $order_id = $id;
        $order_model = new OrderModel();
        $order_data = $order_model->where('id', $id)->field('order_status,goods_type,user_id')->find();
        if (empty($order_data)) {
            $res['code'] = 10;
            $res['msg'] = "取消失败";
            return self::returnMsg($res);
        }
//        if (intval($order_data['goods_type'])) {
//            $res['code'] = 20;
//            $res['msg'] = "取消失败";
//            return self::returnMsg($res);
//        }
        if (intval($order_data['order_status']) == 1) {
            $res = $order_model->cancelOrder($order_id, $order_data['user_id']);
        } else if (intval($order_data['order_status']) == 2) {
            $retx = $order_model->refundOrder($order_id);
            $order_item_model = new OrderItemModel();
            $ret = $order_item_model->cancelOrderStore($order_id);
            if ($ret === false || $retx === false) {
                $res['code'] = 0;
                $res['msg'] = "订单状态更新出错";
            } else {
                $res['code'] = 1;
                $res['msg'] = "取消订单退款成功";
            }
        }
        return self::returnMsg($res);
    }

    /**
     * 平台付款指定订单
     * @param $id
     * @return \think\response\Json
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onPayOrder($id)
    {
        $res['code'] = 0;
        $res['msg'] = "付款失败";
        $order_id = $id;
        $order_model = new OrderModel();
        $order_data = $order_model->where('id', $id)->field('order_status,goods_type,user_id')->find();
        if (empty($order_data)) {
            $res['code'] = 10;
            $res['msg'] = "付款失败";
            return self::returnMsg($res);
        }
        if (intval($order_data['goods_type'])) {
            $res['code'] = 20;
            $res['msg'] = "付款失败";
            return self::returnMsg($res);
        }
        if (intval($order_data['order_status']) == 1) {
            $res = $order_model->payOrder($order_id, $order_data['user_id']);
        }
        return self::returnMsg($res);
    }

    /**
     * 修改订单各项金额
     * @param Request $request
     * @return \think\response\Json
     */
    public function onSetOrderPrice(Request $request)
    {
        $id = $request->param("id");
        $price = $request->param("price");//freight运费，difference差价，actual实际收款，cost实际成本 数组
        $res = $this->model->setOrderPrice($id, $price);
        return self::returnMsg($res);
    }

    /**
     * 修改收货地址
     * @param Request $request
     * @return \think\response\Json
     */
    public function onSetTakeAddress(Request $request)
    {
        $id = $request->param("id");
        $phone = $request->param("phone");
        $name = $request->param("name");
        $address = $request->param("address");
        $res = $this->model->setTakeAddress($id, $phone, $name, $address);
        return self::returnMsg($res);
    }

    /**
     * 修改收货地址
     * @param Request $request
     * @return \think\response\Json
     */
    public function onSetLogisticsNumber(Request $request)
    {
        $id = $request->param("id");
        $numbers = $request->param("numbers"); //id logistics_number
        $res = $this->model->setLogisticsNumber($id, $numbers);
        return self::returnMsg($res);
    }

    /**
     * 订单实际收款金额修改
     * @param Request $request
     * @return \think\response\Json
     */
    public function onSetPayOrder(Request $request)
    {
        $formData = $request->param();
        $order_id = $formData['order_id'];
        $actual_price = $formData['actual_price'];
        if (empty($order_id)) {
            $res['code'] = 0;
            $res['msg'] = "参数有误";
            return self::returnMsg($res);
        }
        $res = $this->model->handleOrderStatus($order_id, $actual_price);
        return self::returnMsg($res);
    }

    /**
     * 导出订单
     * @param string $start
     * @param string $end
     * @param int $order_status
     * @throws \PHPExcel_Exception
     * @throws \PHPExcel_Writer_Exception
     */
    public function onExportOrder($start = '', $end = '', $order_status = 0)
    {

//        $objPHPExcel = new \PHPExcel();
//        // 设置sheet
//        $objPHPExcel->setActiveSheetIndex(0);
//        // 设置列的宽度
//        $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(20);
//        $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(20);
//        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(20);
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle("订单商品详情单");
        $title = date("Y-m-d") . "_待发货订单";
        $fields = ['create_time', 'order_sn', 'pay_sn', 'goods_title', 'attribute_names', 'goods_number', 'goods_price',
            'goods_price_all', 'status_str', 'handle_status', 'take_name', 'take_phone', 'take_address'];
        if (!is_array($fields)) {
            return false;
        }
        //首先我们先定义号每个字段的含义  键是数据库里的字段名  值是含义
        $field_title = [
            'create_time' => '下单时间',
            'order_sn' => '订单编号',
            'pay_sn' => '支付编号',
            'goods_title' => '商品名称',
            'attribute_names' => '商品规格',
            'goods_number' => '商品数量',
            'goods_price' => '商品数量',
            'goods_price_all' => '总价格',
            'status_str' => '订单状态',
            'handle_status' => '是否退款',
            'take_name' => '用户名称',
            'take_phone' => "电话",
            'take_address' => "地址"
        ];
        $data_list_arr[] = $field_title;
        $field_res = [];
        //然后根据所需导出的字段组成相应的结果集
        foreach ($fields as $k => $v) {
            $field_res[$k]['title'] = $field_title[$v];
            $field_res[$k]['field'] = $v;
        }

        if (!empty($start)) {
            $time_start = $start / 1000;
            $time_end = $end / 1000;
            $time = [$time_start, $time_end];
        } else {
            $time = [time() - 90 * 86400, time()];
        }
        $map = [];
        if (!empty($order_status)) {
            $map = [
                'o.order_status' => $order_status
            ];
        }

        $field = "a.*,b.nick_name,d.goods_title,o.freight_price,o.take_name,o.take_address,o.take_phone,o.order_status as order_status_str,o.out_handle_status";
        $order = "a.create_time desc,a.order_status asc";

        $model = new OrderItemModel();
        $dataList = $model
            ->where($map)
            ->whereBetween('a.create_time', $time)
            ->alias("a")
            ->join("t_user b", "a.user_id=b.id")
            ->leftJoin("t_order o", "a.order_id=o.id")
            ->leftJoin("t_goods_common d", "a.goods_id=d.goods_id")
            ->group('a.id')
            ->field($field)
            ->order($order)
            ->paginate(['page' => 1, 'list_rows' => 10000], false);
        $data_list = $dataList->items();
        //存取数据
        foreach ($data_list as $k => $v) {
            $handle_status = "无";
            if (intval($v['out_handle_status']) > 0) {
                $handle_status = "已退款";
            }
            $status_str = "已付款";
            //0订单取消 1待付款 2已付款 3已发货 4已收货 5已完成（售后时间之后）
            switch (intval($v['order_status_str'])) {
                case 1:
                    $status_str = "待付款";
                    break;
                case 2:
                    $status_str = "已付款";
                    break;
                case 3:
                    $status_str = "已发货";
                    break;
                case 4:
                    $status_str = "已收货";
                    break;
                case 5:
                    $status_str = "已完成";
                    break;
            }
            $data_list_arr[] = [
                'create_time' => $v['create_time'],
                'order_sn' => "'" . $v['order_sn'],
                'pay_sn' => $v['pay_sn'],
                'goods_title' => $v['goods_title'],
                'attribute_names' => $v['attribute_names'],
                'goods_number' => $v['goods_number'],
                'goods_price' => $v['goods_price'],
                'goods_price_all' => round($v['goods_number'] * $v['goods_price'], 2),
                'status_str' => $status_str,
                'handle_status' => $handle_status,
                'take_name' => $v['take_name'],
                'take_phone' => "'" . $v['take_phone'],
                'take_address' => $v['take_address']
            ];
        }
        $index = 1;
        foreach ($data_list_arr as $keys => $value) {
            foreach ($field_res as $k => $v) {
                $column = Coordinate::stringFromColumnIndex($k + 1);
                $sheet->setCellValue($column . $index, $value[$v['field']]);
            }
            $index++;
        }
        $column_index = 1;
        foreach ($field_title as $value) {
            $column = Coordinate::stringFromColumnIndex($column_index);
            $sheet->getColumnDimension($column)->setAutoSize(true);
            $column_index++;
        }
        $styleArray1 = [
            'borders' => [
                'allBorders' => [
                    'borderStyle' => Border::BORDER_THIN    //细边框
                ]
            ]
        ];
        $sheet->getStyle('A1' . ':' . 'M' . $index)->applyFromArray($styleArray1);
        $filename = urlencode($title) . '.xlsx';

        // make file
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header("Content-Disposition: attachment;filename=$filename");
        header('Cache-Control: max-age=0');
        header('Pragma: public');
        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
        $writer->save('php://output');
        exit;

    }

    /**
     * 获取进货商统计
     * @param string $distributor_id
     * @param string $keyword
     * @param int $page
     * @param int $limit
     * @param array $time_section
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function onDistributorPage($distributor_id = '', $keyword = '', $page = 1, $limit = 10, $time_section = [])
    {
        $time = '';
        if (!empty($time_section)) {
            $time_start = strtotime($time_section[0]);
            $time_end = strtotime($time_section[1]);
            $time = [$time_start, $time_end];
        }
        $order_item_model = new OrderItemModel();
        $data = $order_item_model->getPageData($distributor_id, $keyword, $page, $limit, $time);
        return self::returnMsg(1, [
            'totalCount' => $data['total'],
            'currentPage' => $data['current'],
            'pageList' => $data['dataList']
        ]);
    }

}
